<?php
class gSeccode {
	public static function output() {
		header('Content-type: image/png');
		self::GBVerify();
	}
	public static function check($data) {
		$sec = gSession::get('seccode');
		$md5 = md5(strtoupper($data['seccode']));
		$k = array_search($md5, $sec);
		if($k===false) return false;
		$k -= $k % 2;
		unset($sec[$k]);
		unset($sec[$k+1]);
		gSession::set('seccode', $sec);
		return true;
	}
	private static function addCode($code) {
		$sec = gSession::get('seccode');
		if(!is_array($sec)) {
			$sec = array(md5($code), md5(self::toFirst($code)));
		} else {
			if(count($sec) > 10) {
				array_shift($sec);
				array_shift($sec);
			}
			$sec[] = md5($code);
			$sec[] = md5(self::toFirst($code));
		}
		gSession::set('seccode', $sec);
	}
	private static function GBVerify($length=4,$type='png',$width=180,$height=50,$fontface='simhei.ttf') {
		import('ORG.Util.Image');
		import('ORG.Util.String');
    $code = String::rand_string($length,4);
    self::addCode($code);
    $width = ($length*45)>$width?$length*45:$width;
		$im=imagecreatetruecolor($width,$height);
		$borderColor = imagecolorallocate($im, 100, 100, 100);                    //边框色
		$bkcolor=imagecolorallocate($im,250,250,250);
		imagefill($im,0,0,$bkcolor);
		@imagerectangle($im, 0, 0, $width-1, $height-1, $borderColor);
		// 干扰
		for($i=0;$i<15;$i++){
			$fontcolor=imagecolorallocate($im,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
			imagearc($im,mt_rand(-10,$width),mt_rand(-10,$height),mt_rand(30,300),mt_rand(20,200),55,44,$fontcolor);
		}
		for($i=0;$i<255;$i++){
			$fontcolor=imagecolorallocate($im,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
			imagesetpixel($im,mt_rand(0,$width),mt_rand(0,$height),$fontcolor);
		}
		if(!is_file($fontface)) {
			$fontface = dirname(__FILE__)."/".$fontface;
		}
		for($i=0;$i<$length;$i++){
			$fontcolor=imagecolorallocate($im,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120)); //这样保证随机出来的颜色较深。
			$codex= String::msubstr($code,$i,1);
			imagettftext($im,mt_rand(18,28),mt_rand(-20,20),40*$i+30*mt_rand(20,100)/100,mt_rand(30,35),$fontcolor,$fontface,$codex);
		}
		Image::output($im,$type);
	}
	
	private static function pyFirst($s) {
		$asc=ord($s{0})*256+ord($s{1})-65536; 
		if($asc>=-20319 and $asc<=-20284)return "A"; 
		if($asc>=-20283 and $asc<=-19776)return "B"; 
		if($asc>=-19775 and $asc<=-19219)return "C"; 
		if($asc>=-19218 and $asc<=-18711)return "D"; 
		if($asc>=-18710 and $asc<=-18527)return "E"; 
		if($asc>=-18526 and $asc<=-18240)return "F"; 
		if($asc>=-18239 and $asc<=-17923)return "G"; 
		if($asc>=-17922 and $asc<=-17418)return "H"; 
		if($asc>=-17417 and $asc<=-16475)return "J"; 
		if($asc>=-16474 and $asc<=-16213)return "K"; 
		if($asc>=-16212 and $asc<=-15641)return "L"; 
		if($asc>=-15640 and $asc<=-15166)return "M"; 
		if($asc>=-15165 and $asc<=-14923)return "N"; 
		if($asc>=-14922 and $asc<=-14915)return "O"; 
		if($asc>=-14914 and $asc<=-14631)return "P"; 
		if($asc>=-14630 and $asc<=-14150)return "Q"; 
		if($asc>=-14149 and $asc<=-14091)return "R"; 
		if($asc>=-14090 and $asc<=-13319)return "S"; 
		if($asc>=-13318 and $asc<=-12839)return "T"; 
		if($asc>=-12838 and $asc<=-12557)return "W"; 
		if($asc>=-12556 and $asc<=-11848)return "X"; 
		if($asc>=-11847 and $asc<=-11056)return "Y"; 
		if($asc>=-11055 and $asc<=-10247)return "Z"; 
		return "?";
	}
	private static function toFirst($str){
		$str=iconv("UTF-8","gb2312", $str);
		$ret = '';
		while(!empty($str)) {
			$ord=ord($str{0}); 
			if ($ord<128) {
				$ret.=$str{0};
				$str = substr($str,1);
				continue;
			}
			$ret .= self::pyFirst($str);
			$str = substr($str,2);
		}
		return strtoupper($ret);
	}
};

?>